//在抽象类中，'抽象方法'本质上是'定义接口规范'：即规定高层类的接口，从而保证所有子类都有相同的接口实现，这样，多态就能发挥出威力。

//如果一个抽象类没有field(字段)，所有method(方法)全部都是抽象方法：
abstract class Person { //只有abstract method
	public abstract void run();
	public abstract String getName();
}

//就可以把该抽象类改写为接口：interface。

//在Java中,使用interface可以声明一个接口:
interface Person {
	void run(); //method
	String getName(); //method
}


//所谓interface，就是比抽象类还要抽象的纯抽象接口，因为它连field(字段)都不能有，只允许存在method。因为interface(接口)定义的所有方法默认都是public abstract的，所以这两个修饰符不需要写出来（写不写效果都一样）。

//当一个具体的class去实现一个interface时，需要使用implements关键字。举个例子：
class Student implements Person {
	private String name;

	public Student(String name) {
		this.name = name;
	}

	@Override //覆写了interface Person的method.run()
	public void run() {
		System.out.println(this.name + " run");
	}

	@Override
	public String getName() {
		return this.name;
	}
}


//我们知道，在Java中，一个类只能继承自另一个类，不能从多个类继承。但是，一个类可以实现多个interface，例如：
class Student implements Person, Hello { // 实现了两个interface
    ...
}



/*
术语
注意区分术语：

Java的接口特指interface的定义，表示一个接口类型和一组方法签名，而编程接口泛指接口规范，如方法签名，数据格式，网络协议等。

抽象类和接口的对比如下：

abstract class	interface
继承		只能extends一个class	可以implements多个interface
字段		可以定义实例字段	 不能定义实例字段
抽象方法		可以定义抽象方法	可以定义抽象方法
非抽象方法	可以定义非抽象方法	可以定义default方法
*/


//在使用的时候，实例化的对象永远只能是某个具体的子类，但总是通过接口去引用它，因为'接口'比'抽象类' 更抽象：
List list = new ArrayList(); //使用List接口引用具体子类的实例
Collection coll = list; //向上转型为Collection接口
Iterable it = coll; //向上转型为Iterable接口




// default方法
//在接口中，可以定义default方法。例如，把Person接口的run()方法改为default方法：
public class Main {
	public static void main(String[] args) {
		Person p = new Student("Xiao Ming");
		p.run();
	}
}

interface Person {
	String getName();
	default void run() {
		System.out.println(getName() + " run");
	}
}

class Student implements Person {
	private String name;

	public Student(String name) {
		this.name = name;
	}

	public String getName() {
		return this.name;
	}
}
//实现类可以不必覆写default方法。default方法的目的是，当我们需要给接口新增一个方法时，会涉及到修改全部子类。如果新增的是default方法，那么子类就不必全部修改，只需要在需要覆写的地方去覆写新增方法。

//default方法和抽象类的普通方法是有所不同的。因为interface没有字段，default方法无法访问字段，而抽象类的普通方法可以访问实例字段。


/*
小结
	1.Java的接口（interface）定义了‘纯抽象规范’，一个类可以implements(实现、实施) 多个接口；

	2.接口也是数据类型，适用于向上转型和向下转型；

	3.接口的所有方法都是抽象方法，接口不能定义实例field(字段)；

	4.接口可以定义default方法（JDK>=1.8）。
*/